package es.esi.gemde.methodmanager.service.handlers;

import java.util.Vector;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;

import es.esi.gemde.methodmanager.CommandConstants;
import es.esi.gemde.methodmanager.service.impl.CommandParametersRegistry;
import es.esi.gemde.modelvalidator.ModelValidatorPlugin;
import es.esi.gemde.modelvalidator.service.IValidationResult;
import es.esi.gemde.modelvalidator.ui.ModelValidatorUI;

public class LaunchValidationCommandHandler extends AbstractHandler {
	
	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		String val = event.getParameter(CommandConstants.VALIDATION_PARAM_ID);
		if (val == null) {
			throw new ExecutionException("No validation was provided. Failed to launch the validation.");
		}
		
		String modelfile = event.getParameter(CommandConstants.MODELFILE_PARAM_ID);
		String eobject = event.getParameter(CommandConstants.EOBJECT_PARAM_ID);
		
		if (modelfile != null) {
			ResourceSet rs = new ResourceSetImpl();
			Resource r = rs.getResource(URI.createFileURI(modelfile), false);
			
			if (r == null) {
				throw new ExecutionException("Failed to load the provided model. Failed to launch the validation.");
			}
			
			Vector<EObject> targets = new Vector<EObject>();
			TreeIterator<EObject> ti = r.getAllContents();
			while (ti.hasNext()) {
				targets.add(ti.next());
			}
			
			try {
				ModelValidatorPlugin.getServer().runValidation(val, targets);
			} catch (Exception e) {
				throw new ExecutionException("Validation returned an exception.", e);
			}
		}
		else if (eobject != null) {
			Object param = CommandParametersRegistry.instance().getParam(eobject);
			if (param == null || !(param instanceof EObject)) {
				throw new ExecutionException("Provided EObject is not valid. Failed to launch the validation.");
			}
			
			Vector<EObject> targets = new Vector<EObject>();
			targets.add((EObject)param);
			TreeIterator<EObject> ti = ((EObject)param).eAllContents();
			while (ti.hasNext()) {
				targets.add(ti.next());
			}
			
			IValidationResult res = null;
			
			try {
				res = ModelValidatorPlugin.getServer().runValidation(val, targets);
			} catch (Exception e) {
				throw new ExecutionException("Validation returned an exception.", e);
			}
			
			ModelValidatorUI.showValidationResults(res);
		}
		else {
			throw new ExecutionException("No elements to validate were provided. Failed to launch the validation.");
		}
		
		return null;
	}

}